﻿namespace EFS.RC.SupervisorCentral.Controls
{
	/// Class MainWindow
	public partial class MainWindow : EFS.RC.ClientPlatform.UI.MainWindow
	{
		#region Composition

		/// all agents main controls
		private System.Collections.Generic.Dictionary<System.String, EFS.RC.SupervisorCentral.Controls.Agents.Main> controlsAgentMain =
			new System.Collections.Generic.Dictionary<System.String, EFS.RC.SupervisorCentral.Controls.Agents.Main>();

		// all end points
		private System.Collections.Generic.Dictionary<System.String, EFS.RC.CC.Messages.Application.CustomerEndPoint> customerEndPoints =
			new System.Collections.Generic.Dictionary<System.String, EFS.RC.CC.Messages.Application.CustomerEndPoint>();
		
		#endregion

		#region Delegates
		
		/// LoadEndPointsDelegate
		private delegate void LoadEndPointDelegate(EFS.RC.CC.Messages.Application.CustomerEndPoint customerEndPointMsg);

		/// LoadEndPointsDelegate
		private delegate void UpdateHuntQueueStatusListDelegate(EFS.RC.CC.Messages.HuntQueue.StatusList statusListMsg);

		#endregion

		#region Constructors
	
		/// Implicit
		public MainWindow()
		{
			InitializeComponent();

			// add key down event
			AddHandler(System.Windows.Input.Keyboard.KeyDownEvent, (System.Windows.Input.KeyEventHandler)HandleKeyDownEvent);

			// init ui
			InitUI();
		}

		#endregion

		#region UI

		/// InitUI
		private void InitUI()
		{
			// ignore in design tool
			if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
			{
				// clear all
				ClearUIPhones();
			}
		}

		/// AddCustomerEndPoint
		private void AddCustomerEndPoint(EFS.RC.CC.Messages.Application.CustomerEndPoint customerEndPoint)
		{
			// keep;
			customerEndPoints[customerEndPoint.PhoneUri] = customerEndPoint;

			// filter phones
			System.String filterPhonesValue = EFS.RC.SupervisorCentral.Common.Config.AppSettings.FilterPhones;

			// create array
			System.Collections.Generic.List<System.String> phones = new System.Collections.Generic.List<System.String>();
			foreach (System.String phone in customerEndPoints.Keys)
			{
				// check filtered
				if (EFS.Common.Verify.String(filterPhonesValue) && filterPhonesValue.IndexOf(phone) < 0)
				{
					continue;
				}

				// add to list
				phones.Add(phone);
			}

			// load
			LoadPhones(phones.ToArray());

			// create new tab item
			/*System.Windows.Controls.TabItem tabItem = new System.Windows.Controls.TabItem();
			tabItem.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
			tabItem.VerticalContentAlignment = System.Windows.VerticalAlignment.Stretch;
			tabItem.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
			tabItem.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Stretch;
			tabItem.Margin = new System.Windows.Thickness(0, 0, 0, 0);
			tabItem.Header = customerEndPoint.PhoneUri;
			tabControlMain.Items.Add(tabItem);

			// create new control
			EFS.RC.SupervisorCentral.Controls.Agents.Main controlMain = new EFS.RC.SupervisorCentral.Controls.Agents.Main();
			controlMain.CustomerEndPoint = customerEndPoint;
			controlMain.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
			controlMain.VerticalContentAlignment = System.Windows.VerticalAlignment.Stretch;
			controlMain.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
			controlMain.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Stretch;
			controlMain.Margin = new System.Windows.Thickness(0, 0, 0, 0);
			controlsAgentMain[customerEndPoint.PhoneUri] = controlMain;
			controlMain.ContactListItem_OnButtonClickedDlg += ContactListItem_OnButtonClicked;
			tabItem.Content = controlMain;

			tabControlMain.SelectedIndex = 0;*/
		}

		#endregion

		#region Utilities
		/// GetPhonesGridRowColumns
		private static System.Int32[] GetPhonesGridRowsColumns(System.Int32 count)
		{
			// compute
			System.Int32 columns = (System.Int32)System.Math.Ceiling(System.Math.Sqrt(count));
			System.Int32 lines = (System.Int32)System.Math.Ceiling(count / (System.Double)columns);

			// ok
			return new System.Int32[2] { lines, columns };
		}

		/// ClearUIPhones
		private void ClearUIPhones()
		{
			// remove all others
			controlsAgentMain.Clear();
			gridPhones.RowDefinitions.Clear();
			gridPhones.ColumnDefinitions.Clear();

			// cicle all and reset
			gridPhones.Children.Clear();
		}

		/// Load phones
		private void LoadPhones(System.String[] phones)
		{
			// check
			EFS.Common.Verify.Reference(phones, "phones");

			// remove all others
			ClearUIPhones();

			// test length
			if (0 == phones.Length)
			{
				return;
			}

			// get rows and columns
			System.Int32[] gridRowsColumnsCount = GetPhonesGridRowsColumns(phones.Length);
			System.Int32 gridRowsCount = gridRowsColumnsCount[0];
			System.Int32 gridColumnsCount = gridRowsColumnsCount[1];

			// cicle all
			System.Int32 countAdded = 0;

			// cicle rows
			for (System.Int32 i = 0; i < gridRowsCount; ++i)
			{
				// add row definition
				System.Windows.Controls.RowDefinition rowDefinition = new System.Windows.Controls.RowDefinition();
				gridPhones.RowDefinitions.Add(rowDefinition);

				for (System.Int32 j = 0; j < gridColumnsCount; ++j)
				{
					if (countAdded >= phones.Length)
					{
						break;
					}

					// get phone
					System.String phone = phones[i + j];

					// columnDefinition
					System.Windows.Controls.ColumnDefinition columnDefinition = null;

					// add separator
					if (j > 0)
					{
						// add row definition
						columnDefinition = new System.Windows.Controls.ColumnDefinition();
						columnDefinition.Width = new System.Windows.GridLength(20, System.Windows.GridUnitType.Pixel);
						gridPhones.ColumnDefinitions.Add(columnDefinition);
					}

					// add row definition
					columnDefinition = new System.Windows.Controls.ColumnDefinition();
					gridPhones.ColumnDefinitions.Add(columnDefinition);

					// craete control
					EFS.RC.SupervisorCentral.Controls.Agents.Main controlMain = new EFS.RC.SupervisorCentral.Controls.Agents.Main();
					controlMain.CustomerEndPoint = customerEndPoints[phone];
					controlMain.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
					controlMain.VerticalContentAlignment = System.Windows.VerticalAlignment.Stretch;
					controlMain.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
					controlMain.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Stretch;
					controlMain.Margin = new System.Windows.Thickness(0, 0, 0, 0);
					controlMain.ContactListItem_OnButtonClickedDlg += ContactListItem_OnButtonClicked;

					// add to hash
					controlsAgentMain[phone] = controlMain;

					// grid column
					System.Int32 gridColumn = j;
					if (j > 0)
					{
						gridColumn = j * 2;
					}

					// add to grid
					gridPhones.Children.Add(controlMain);
					System.Windows.Controls.Grid.SetRow(controlMain, i);
					System.Windows.Controls.Grid.SetColumn(controlMain, gridColumn);

					// increment added
					++countAdded;
				}
			}
		}

		/// Load EndPoints
		private void LoadEndPoint(EFS.RC.CC.Messages.Application.CustomerEndPoint customerEndPointMsg)
		{
			// test & update
			if (!EFS.Common.UI.Shared.WindowHelper.IsDisposed(this))
			{
				AddCustomerEndPoint(customerEndPointMsg);
			}
		}

		/// Load agents
		private void AddUpdateAgents()
		{
			// test & update
			if (!EFS.Common.UI.Shared.WindowHelper.IsDisposed(this))
			{
				// cicle all
				foreach (EFS.RC.SupervisorCentral.Controls.Agents.Main agentsMainCtrl in controlsAgentMain.Values)
				{
					this.Dispatcher.Invoke(
						new EFS.RC.SupervisorCentral.Controls.Agents.List.LoadAgentsDelegate(agentsMainCtrl.AddUpdateAgents),
						null);
				}
			}
		}

		/// UpdateHuntQueueStatusList
		private void UpdateHuntQueueStatusList(EFS.RC.CC.Messages.HuntQueue.StatusList statusListMsg)
		{
			// test & update
			if (EFS.Common.UI.Shared.WindowHelper.IsDisposed(this))
			{
				return;
			}

			// cicle all
			foreach (EFS.RC.CC.Messages.HuntQueue.Status status in statusListMsg.Items)
			{
				if (!controlsAgentMain.ContainsKey(status.PhoneUri))
				{
					continue;
				}

				// get & set
				EFS.RC.SupervisorCentral.Controls.Agents.Main ctrlMain = controlsAgentMain[status.PhoneUri];
				ctrlMain.controlAgentsACD.controlListBusyInHunt.controlRibbonInHunt.WC = status.WaitCount;
				ctrlMain.controlAgentsACD.controlListBusyInHunt.controlRibbonInHunt.LWT = new System.TimeSpan(status.LongestWatingTime);
			}
		}

		/// <summary>
		/// apply filter
		/// </summary>
		private void ApplyPhonesFilter()
		{
			// filter phones
			System.String filterPhonesValue = EFS.RC.SupervisorCentral.Common.Config.AppSettings.FilterPhones;
			if (EFS.Common.Verify.String(filterPhonesValue))
			{
				// check eny new and add
				System.String[] phones = filterPhonesValue.Split(new System.Char[] { ';' }, System.StringSplitOptions.RemoveEmptyEntries);

				// load phones
				LoadPhones(phones);
			}
		}
		#endregion

		#region ControlEvents

		// check lync
		private System.Boolean CheckLync()
		{
			// check lync
			try
			{
				Microsoft.Lync.Model.LyncClient.GetAutomation();
				return true;
			}
			catch (System.Exception)
			{
				// show meesage
				ShowMessage("Lync Communicator must be Started", "Start Lync Communicator", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Hand);

				// done
				return false;
			}
		}

		/// ContactListItem_OnButtonClicked
		private void ContactListItem_OnButtonClicked(
			System.Windows.RoutedEventArgs routedEventArgs,
			EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem.eButtonType buttonType,
			System.String agentSIP,
			System.String acd)
		{
			// switch button
			switch (buttonType)
			{
				case EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem.eButtonType.Listen:
				{
					// check lync
					if (!CheckLync())
					{
						return;
					}

					// create message
					EFS.RC.CC.Messages.Message msg = new EFS.RC.CC.Messages.Supervisor.Tools.Monitor(agentSIP);

					// send message
					SendUCMAMessage(msg);

					// break
					break;
				}
				case EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem.eButtonType.AddToACD:
				{
					// create message
					EFS.RC.CC.Messages.Agents.ACD msg = new EFS.RC.CC.Messages.Agents.ACD();
					msg.AgentSIP = agentSIP;
					msg.EndPointTel = acd;
					msg.Enable = true;

					// send message
					SendUCMAMessage(msg);

					// break
					break;
				}
				case EFS.RC.SupervisorCentral.Controls.Agents.ContactListItem.eButtonType.RemoveFromACD:
				{
					// create message
					EFS.RC.CC.Messages.Agents.ACD msg = new EFS.RC.CC.Messages.Agents.ACD();
					msg.AgentSIP = agentSIP;
					msg.EndPointTel = acd;
					msg.Enable = false;

					// send message
					SendUCMAMessage(msg);

					// break
					break;
				}
				default:
				{
					break;
				}
			}
		}

		/// HandleKeyDownEvent
		private void HandleKeyDownEvent(System.Object sender, System.Windows.Input.KeyEventArgs e)
		{
			// CTRL + something
			if ((System.Windows.Input.Keyboard.Modifiers & System.Windows.Input.ModifierKeys.Control) == System.Windows.Input.ModifierKeys.Control)
			{
				// Q
				if (e.Key == System.Windows.Input.Key.Q)
				{
					ClosePlatform();
				}
			}
		}
		#endregion

		#region MenuEvents

		/// File
		private void menuItemFile_Click(object sender, System.Windows.RoutedEventArgs e)
		{
			System.Windows.Controls.MenuItem mi = e.Source as System.Windows.Controls.MenuItem;

			switch (mi.Name)
			{
				case "menuItemFileExit":
				{
					ClosePlatform();
					break;
				}
				default:
				{
					break;
				}
			}
		}

		/// File
		private void menuItemTools_Click(object sender, System.Windows.RoutedEventArgs e)
		{
			System.Windows.Controls.MenuItem mi = e.Source as System.Windows.Controls.MenuItem;

			switch (mi.Name)
			{
				case "menuItemToolsSurvey":
					{
						// create list
						EFS.RC.SupervisorCentral.Controls.Conversations.Surveys.List surveyList = new EFS.RC.SupervisorCentral.Controls.Conversations.Surveys.List();
						surveyList.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
						surveyList.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;

						// create dialog
						EFS.Common.UI.Controls.ModalDialogHost surveyListHost = new EFS.Common.UI.Controls.ModalDialogHost();
						surveyListHost.Title = "Monitoring List";
						surveyListHost.ResizeMode = System.Windows.ResizeMode.NoResize;
						surveyListHost.HostedContent = surveyList;
						surveyListHost.ShowDialog();
						break;
					}
				case "menuItemToolsFilterPhones":
					{
						EFS.RC.SupervisorCentral.Controls.FilterPhones filter = new FilterPhones(customerEndPoints.Keys);
						filter.Owner = this;
						filter.ShowDialog();
						ApplyPhonesFilter();
						break;
					}
				case "menuItemToolsAdmin":
					{
						EFS.RC.SupervisorCentral.Controls.Admin admin = new Admin();
						admin.Owner = this;
						admin.ShowDialog();
						break;
					}
				case "menuItemToolsThresholds":
					{
						EFS.RC.SupervisorCentral.Controls.ThresholdsPhones phoneSelect = new ThresholdsPhones(customerEndPoints.Keys);
						phoneSelect.Owner = this;
						phoneSelect.ShowDialog();

						if (EFS.Common.Verify.String(phoneSelect.SelectedPhone))
						{
							EFS.RC.SupervisorCentral.Controls.Thresholds tresholds = new Thresholds(phoneSelect.SelectedPhone);
							tresholds.Owner = this;
							tresholds.ShowDialog();
						}
						break;
					}
				default:
					{
						break;
					}
			}
		}

		#endregion

		#region Messages & Session

		// terminated
		protected override void SessionTerminatedCleanup()
		{
			// clear
			ClearUIPhones();
			//tabControlMain.Items.Clear();
		}

		/// Process Message entry point
		protected override void ProcessUCMAMessage(EFS.RC.CC.Messages.Message message)
		{
			try
			{
				// test message
				if (null != message)
				{
					// CustomerEndPointList
					if (message is EFS.RC.CC.Messages.Application.CustomerEndPoint)
					{
						ProcessUCMAMessage_CustomerEndPoint(message as EFS.RC.CC.Messages.Application.CustomerEndPoint);
					}
					// Agents StatusList
					else if (message is EFS.RC.CC.Messages.Agents.StatusList)
					{
						ProcessUCMAMessage_AgentsStatusList(message as EFS.RC.CC.Messages.Agents.StatusList);
					}
					// HuntQueue StatusList
					else if (message is EFS.RC.CC.Messages.HuntQueue.StatusList)
					{
						ProcessUCMAMessage_HuntQueueStatusList(message as EFS.RC.CC.Messages.HuntQueue.StatusList);
					}
					else if (message is EFS.RC.CC.Messages.Application.Configs.CH)
					{
						ProcessUCMAMessage_ConfigCH(message as EFS.RC.CC.Messages.Application.Configs.CH);
					}
                    else if (message is EFS.RC.CC.Messages.Error)
                    {
                        ShowMessage("Error", (message as EFS.RC.CC.Messages.Error).Text, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
                    }
                }
			}
			catch (System.Exception ex)
			{
				EFS.EventLog.Log.LogException(ex, null);
			}
		}

		/// CustomerEndPointList
		private void ProcessUCMAMessage_CustomerEndPoint(EFS.RC.CC.Messages.Application.CustomerEndPoint customerEndPointMsg)
		{
			this.Dispatcher.Invoke(
				new LoadEndPointDelegate(LoadEndPoint),
				new System.Object[] { customerEndPointMsg });
		}

		/// StatusList
		private void ProcessUCMAMessage_AgentsStatusList(EFS.RC.CC.Messages.Agents.StatusList statusListMsg)
		{
			// load from 
			EFS.RC.SupervisorCentral.Common.Session.Instance.AgentList.LoadFrom(statusListMsg);

			// invoke
			this.Dispatcher.Invoke(
				new EFS.RC.SupervisorCentral.Controls.Agents.List.LoadAgentsDelegate(AddUpdateAgents),
				null);
		}

		/// StatusList
		private void ProcessUCMAMessage_HuntQueueStatusList(EFS.RC.CC.Messages.HuntQueue.StatusList statusListMsg)
		{
			this.Dispatcher.Invoke(
				new UpdateHuntQueueStatusListDelegate(UpdateHuntQueueStatusList),
				new System.Object[] { statusListMsg });
		}

		/// Config CH
		private void ProcessUCMAMessage_ConfigCH(EFS.RC.CC.Messages.Application.Configs.CH configCHMessage)
		{
			// set conection string
			EFS.RC.CC.CH.Config.Settings.QrdConnectionString = configCHMessage.ConnectionString;
		}

		#endregion
	}

}